<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xf="http://www.w3.org/2002/xforms" 
  xmlns:dyn="http://icl.com/saxon"
  xmlns:str="http://exslt.org/strings"
  xmlns:func="http://exslt.org/functions"
  xmlns:local="urn:local"
  extension-element-prefixes="dyn str func"
  >
<!-- note: when exslt upgrade, can replate saxon w/
     xmlns:dyn="http://exslt.org/dynamic" 
     -->

<xsl:output method='html' 
  doctype-public='-//W3C//DTD HTML 4.01//EN'
  omit-xml-declaration='yes'/>

<xsl:strip-space elements='*'/>

<xsl:param name="list-size" select='5'/>
<xsl:param name='encode-instance-data'/>

<xsl:variable name='urlencoding' select='"application/x-www-urlencoded"'/>
<xsl:variable name='instance-nodename' select='"xf:instance"'/>
<xsl:template match='xf:caption|xf:hint|xf:model'/>

<!-- the version id -->
<xsl:template match='/'>
  <xsl:comment>
    Form Generated by:
      $Id: xforms.xsl,v 1.12 2002/10/13 23:14:38 rick Exp $
  </xsl:comment>
  <xsl:text>
  </xsl:text>
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<!-- html/non-xforms text nodes -->
<xsl:template match='*'>
  <xsl:copy>
    <xsl:apply-templates select='@*'/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<!-- and their attributes -->
<xsl:template match='@*'>
  <xsl:copy/>
</xsl:template>

<!-- the meat of the matter, outermost groups -->
<xsl:template match='xf:group[not(ancestor::xf:group)]'>
  <form>
    <xsl:for-each select='local:get-model()'>
      <xsl:attribute name='action'>
        <xsl:value-of select='xf:submission/@action'/>
      </xsl:attribute>
      <xsl:attribute name='method'>
        <xsl:value-of select='local:get-form-method()'/>
      </xsl:attribute>
      <xsl:attribute name='id'>
        <xsl:choose>
          <xsl:when test='@id'>
            <xsl:value-of select='@id'/>
          </xsl:when>
          <xsl:otherwise>1</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:for-each>
      <xsl:attribute name='enctype'>
        <xsl:value-of select='local:get-encoding()'/>
      </xsl:attribute>
    <xsl:apply-templates/>
    <xsl:if test='$encode-instance-data and local:get-encoding() != $urlencoding'>
      <xsl:call-template name='encode-instance'/>
    </xsl:if>
  </form>
</xsl:template>

<xsl:template name='encode-instance'>
  <xsl:for-each select='local:get-model()'>
    <input name='_instance' type='hidden'>
      <xsl:attribute name='value'>
        <xsl:text>&lt;?xml version="1.0"?&gt;</xsl:text>
        <xsl:for-each select='xf:instance'>
          <xsl:text>&lt;xforms:instance </xsl:text>
          <xsl:text>xmlns:xforms="http://www.w3.org/2002/01/xforms"</xsl:text>
          <xsl:value-of select='local:encoded-attributes()'/>
          <xsl:text>&gt;</xsl:text>
          <xsl:apply-templates mode='encode'/>
          <xsl:text>&lt;/xforms:instance&gt;</xsl:text>
        </xsl:for-each>
        </xsl:attribute>
    </input>
  </xsl:for-each>
</xsl:template>

<xsl:template match='*' mode='encode'>
  <xsl:value-of select='local:encoded-node()'/>
  <xsl:apply-templates mode='encode'/>
  <xsl:value-of select='local:encoded-node(true())'/>
</xsl:template>

<xsl:template match='text()' mode='encode'>
  <xsl:value-of select='.'/>
</xsl:template>

<!-- CONTROLS -->

<!-- xf:input -->
<xsl:template match='xf:input'>
  <xsl:param name='index'/>
  <xsl:call-template name='input'>
    <xsl:with-param name='index' select='$index'/>
    <xsl:with-param name='type' select='"text"'/>
  </xsl:call-template>
</xsl:template>

<!-- xf:secret -->
<xsl:template match='xf:secret'>
  <xsl:param name='index'/>
  <xsl:call-template name='input'>
    <xsl:with-param name='type' select='"password"'/>
  </xsl:call-template>
</xsl:template>

<xsl:template match='xf:textarea'>
  <xsl:param name='index'/>
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <div>
      <xsl:call-template name='get-class-attribute'/>
      <xsl:call-template name='hint'/>
      <xsl:call-template name='caption'/>
      <span class='input'>
        <textarea name='{local:get-path($index,false())}'>
          <xsl:call-template name='common-attributes'/>
          <xsl:value-of select='local:get-instance-data($index,true())'/>
        </textarea>
      </span>
    </div>
  </xsl:if>
</xsl:template>

<xsl:template match='xf:output'>
  <xsl:param name='index'/>
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <xsl:variable name='data' select='local:get-instance-data($index)'/>
    <span class='output'>
      <xsl:value-of select='$data'/>
      <input type="hidden"  
        name='{local:get-path($index,false())}'
        value='{$data}'/>
    </span>
  </xsl:if>
</xsl:template>

<xsl:template match='xf:upload'>
  <xsl:param name='index'/>
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <div>
      <xsl:call-template name='get-class-attribute'/>
      <xsl:call-template name='hint'/>
      <xsl:call-template name='caption'/>
      <span class='input'>
        <input 
          name='{local:get-path($index,false())}'
          type='file' accept='{@mediatype}'
          value='{local:get-instance-data($index)}'
          >
          <xsl:call-template name='common-attributes'/>
        </input>
      </span>
    </div>
  </xsl:if>
</xsl:template>

<xsl:template match='xf:range'/>

<!-- xf: button -->
<xsl:template match="xf:trigger">
  <xsl:param name='index'/>
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <button name='{local:get-path($index,false())}'>
      <xsl:if test='@class'>
        <xsl:attribute name='class'>
          <xsl:value-of select='@class'/>
        </xsl:attribute>
      </xsl:if>
      <xsl:value-of select='normalize-space(xf:caption)'/>
    </button>
  </xsl:if>
</xsl:template>

<xsl:template match='xf:submit'>
  <input type='submit'
    value='{local:caption-text()}'
    >
    <xsl:call-template name='hint'/>
    <xsl:call-template name='common-attributes'/>
  </input>
</xsl:template>

<xsl:template match='xf:select1|xf:select'>
  <xsl:param name='index'/>
  <!-- open selection not supported -->
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <xsl:variable name='data' 
      select='local:get-instance-data($index)'/>
    <div>
      <xsl:call-template name='get-class-attribute'/>
      <xsl:call-template name='hint'/>
      <xsl:call-template name='caption'/>
      <span class='input'>
        <xsl:choose>
          <xsl:when test='@appearance="full"'>
            <xsl:call-template name='input-list'>
              <xsl:with-param name='data' select='$data'/>
              <xsl:with-param name='name' 
                select='local:get-path($index,false())'/>
              <xsl:with-param name='index' select='$index'/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name='select-list'>
              <xsl:with-param name='name' 
                select='local:get-path($index,false())'/>
              <xsl:with-param name='data' select='$data'/>
              <xsl:with-param name='index' select='$index'/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </span>
    </div>
  </xsl:if>
</xsl:template>

<xsl:template name='input-list'>
  <xsl:param name='data'/>
  <xsl:param name='name'/>
  <xsl:variable name='type'>
    <xsl:choose>
      <xsl:when test='local-name()="select"'>
        <xsl:value-of select='"checkbox"'/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select='"radio"'/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
    <xsl:apply-templates>
      <xsl:with-param name='index' select='$index'/>
      <xsl:with-param name='data' select='$data'/>
      <xsl:with-param name='eltype' select='"input"'/>
      <xsl:with-param name='selected' select='"checked"'/>
      <xsl:with-param name='type' select='$type'/>
      <xsl:with-param name='elname' select='$name'/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template name='select-list'>
  <xsl:param name='name'/>
  <xsl:param name='data'/>
  <xsl:param name='index'/>
  <select name='{$name}'>
    <xsl:choose>
      <xsl:when test='local-name()="select"'>
        <xsl:attribute name='multiple'>
          <xsl:text>multiple</xsl:text>
        </xsl:attribute>
        <xsl:attribute name='size'>
          <xsl:value-of select='$list-size'/>
        </xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name='size'>
          <xsl:choose>
            <xsl:when test='@appearance="minimal"'>1</xsl:when>
            <xsl:otherwise>
              <xsl:value-of select='$list-size'/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:apply-templates>
      <xsl:with-param name='index' select='$index'/>
      <xsl:with-param name='data' select='$data'/>
      <xsl:with-param name='eltype' select='"option"'/>
      <xsl:with-param name='selected' select='"selected"'/>
    </xsl:apply-templates>
  </select>
</xsl:template>

<xsl:template match='xf:choices'>
  <xsl:param name='eltype'/>
  <xsl:param name='selected'/>
  <xsl:param name='type'/>
  <xsl:param name='elname'/>
  <optgroup label='{local:caption-text()}'>
    <xsl:call-template name='hint'/>
    <xsl:apply-templates>
      <xsl:with-param name='data' select='$data'/>
      <xsl:with-param name='eltype' select='$eltype'/>
      <xsl:with-param name='selected' select='$selected'/>
      <xsl:with-param name='type' select='$type'/>
      <xsl:with-param name='elname' select='$elname'/>
    </xsl:apply-templates>
  </optgroup>
</xsl:template>

<xsl:template name='_item'>
  <xsl:param name='value'/>
  <xsl:param name='caption'/>
  <xsl:param name='data'/>
  <xsl:param name='eltype'/>
  <xsl:param name='selected'/>
  <xsl:param name='type'/>
  <xsl:param name='elname'/>
  <xsl:element name='{$eltype}'>
    <xsl:attribute name='value'><xsl:value-of select='$value'/></xsl:attribute>
    <xsl:for-each select='str:tokenize($data)'>
      <xsl:if test='$eltype = "input"'>
        <xsl:attribute name='name'>
          <xsl:value-of select='$elname'/>
        </xsl:attribute>
        <xsl:attribute name='type'>
          <xsl:value-of select='$type'/>
        </xsl:attribute>
      </xsl:if>
      <xsl:if test='$value=.'>
        <xsl:attribute name='{$selected}'>
          <xsl:value-of select='$selected'/>
        </xsl:attribute>
      </xsl:if>
    </xsl:for-each>
    <xsl:if test='$eltype = "option"'>
      <xsl:value-of select='$caption'/>
    </xsl:if>
  </xsl:element>
  <xsl:if test='$eltype="input"'>
    <xsl:value-of select='$caption'/>
  </xsl:if>
</xsl:template>

<xsl:template match='xf:item'>
  <xsl:param name='eltype'/>
  <xsl:param name='selected'/>
  <xsl:param name='data'/>
  <xsl:param name='type'/>
  <xsl:param name='elname'/>

  <xsl:call-template name='_item'>
    <xsl:with-param name='value' select='xf:value'/>
    <xsl:with-param name='caption' select='xf:caption'/>
    <xsl:with-param name='data' select='$data'/>
    <xsl:with-param name='eltype' select='$eltype'/>
    <xsl:with-param name='selected' select='$selected'/>
    <xsl:with-param name='type' select='$type'/>
    <xsl:with-param name='elname' select='$elname'/>
  </xsl:call-template>
</xsl:template>

<xsl:template match='xf:itemset'>
  <xsl:param name='data'/>
  <xsl:param name='eltype'/>
  <xsl:param name='selected'/>
  <xsl:param name='type'/>
  <xsl:param name='elname'/>
  <xsl:variable name='caption' select='xf:caption/@ref'/>
  <xsl:variable name='value' select='xf:value/@ref'/>
  <xsl:variable name='path' select='local:get-path(1,true())'/>
  <xsl:for-each select='local:get-model()'>
    <xsl:for-each select='dyn:evaluate($path)'>
      <xsl:call-template name='_item'>
        <xsl:with-param name='value' select='dyn:evaluate($value)'/>
        <xsl:with-param name='caption' select='dyn:evaluate($caption)'/>
        <xsl:with-param name='data' select='$data'/>
        <xsl:with-param name='eltype' select='$eltype'/>
        <xsl:with-param name='selected' select='$selected'/>
        <xsl:with-param name='type' select='$type'/>
        <xsl:with-param name='elname' select='$elname'/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

<xsl:template match='xf:group'>
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <xsl:choose>
      <xsl:when test='@class="no-display"'>
        <xsl:apply-templates/>
      </xsl:when>
      <xsl:otherwise>
        <div>
          <xsl:call-template name='common-attributes'/>
          <xsl:call-template name='hint'/>
          <span class='group-caption'>
            <xsl:value-of select='local:caption-text()'/>
          </span>
          <xsl:apply-templates/>
        </div>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>

<xsl:template match='xf:repeat'>
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <div>
      <xsl:call-template name='get-class-attribute'/>
      <xsl:call-template name='caption'/>
      <span class='input'>
        <xsl:variable name='context' select='node()'/>
        <xsl:variable name='path' select='local:get-path(1,true())'/>
        <xsl:variable name='min'
          select='local:get-constraint("@minOccurs")'/>
        <xsl:variable name='max' 
          select='local:get-constraint("@maxOccurs")'/>
        <xsl:for-each select='local:get-model()'>
          <xsl:variable name='loop'>
            <xsl:call-template name='get-repeat'>
              <xsl:with-param name='path' select='$path'/>
              <xsl:with-param name='min' select='$min'/>
              <xsl:with-param name='max' select='$max'/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:for-each select='str:tokenize($loop)'>
            <div class='repeat'>
              <xsl:apply-templates select='$context'>
                <xsl:with-param name='index' select='normalize-space(.)'/>
              </xsl:apply-templates>
            </div>
          </xsl:for-each>
        </xsl:for-each>  
      </span>
    </div>
  </xsl:if>
</xsl:template>

<!-- functions and utility (called) templates -->
<func:function name="local:get-instance-data">
  <xsl:param name='index'/>
  <xsl:param name='no-normalize'/>
  <xsl:variable name='path'>
    <xsl:value-of select='local:get-path($index)'/>
  </xsl:variable>
  <func:result>
    <xsl:if test='$path !=""'>
      <xsl:for-each select='local:get-model()'>
        <xsl:variable name='data'>
          <xsl:choose>
            <xsl:when test='starts-with($path,$instance-nodename)'>
              <xsl:value-of select='dyn:evaluate(concat($path,"[1]"))'/>              
            </xsl:when>
            <xsl:otherwise>
              <!-- must be calculate -->
              <xsl:for-each select='./xf:instance'>
                <xsl:value-of select='dyn:evaluate($path)'/>
              </xsl:for-each>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:choose>
          <xsl:when test='$no-normalize'>
            <xsl:value-of select='$data'/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select='normalize-space($data)'/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </xsl:if>
  </func:result>
</func:function>

<func:function name='local:get-model'>
  <!-- Question: unclear in the spec: do child elements
       inherit their parents model?? For now, assume yes -->
  <xsl:param name='model' select='ancestor-or-self::xf:*/@model'/>
  <xsl:choose>
    <xsl:when  test='$model'>
      <func:result select='//xf:model[@id=$model]'/>
    </xsl:when>
    <xsl:otherwise>
      <func:result select='//xf:model[1]'/>
    </xsl:otherwise>
  </xsl:choose>
</func:function>

<func:function name='local:get-path'>
  <xsl:param name='index'/>
  <xsl:param name='use-full-path' select='true()'/>
  <xsl:variable name='path'>
    <xsl:choose>
      <xsl:when test='@bind'>
        <xsl:variable name='id' select='@bind'/>
        <xsl:for-each select='local:get-model()'>
          <xsl:for-each select='descendant::xf:bind[@id=$id]'>
            <xsl:choose>
              <xsl:when test='@calculate and $use-full-path'>
                <xsl:value-of select='@calculate'/>
              </xsl:when>
              <xsl:when test='@nodeset'>
                <xsl:value-of 
                  select='local:get-parent-path($index,@nodeset,$use-full-path)'/>
                <xsl:value-of select='@nodeset'/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of 
                  select='local:get-parent-path($index,@ref,$use-full-path)'/>
                <xsl:value-of select='@ref'/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
        </xsl:for-each>
      </xsl:when>
      <xsl:when test='@nodeset'>
        <xsl:value-of 
          select='local:get-parent-path($index,@nodeset,$use-full-path)'/>
        <xsl:value-of select='@nodeset'/>
      </xsl:when>
      <xsl:when test='@ref'>
        <xsl:value-of 
          select='local:get-parent-path($index,@ref,$use-full-path)'/>
        <xsl:value-of select='@ref'/>
      </xsl:when>
    </xsl:choose>
  </xsl:variable>
  <func:result>
    <xsl:choose>
    <xsl:when 
      test='local:get-encoding() = $urlencoding and not($use-full-path)'>
      <xsl:value-of select='local:basename($path)'/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select='$path'/>
    </xsl:otherwise>
  </xsl:choose>
  </func:result>
</func:function>

<func:function name='local:get-parent-path'>
  <xsl:param name='index'/>
  <xsl:param name='rel-path'/>
  <xsl:param name='use-full-path'/>
  <func:result>
    <xsl:if test='$use-full-path'>
      <xsl:value-of select='$instance-nodename'/>
    </xsl:if>
    <xsl:if test='not(starts-with($rel-path,"/"))'>
      <!-- not absolute path -->
      <xsl:if test='$use-full-path'>
        <xsl:text>/</xsl:text>
      </xsl:if>
      <xsl:for-each select='ancestor::*[
                            @ref 
                            and local-name() != "select1"
                            and local-name() != "select"
                            ]|ancestor::xf:repeat'>
        <xsl:choose>
          <xsl:when test='local-name()="repeat" and @bind'>
            <xsl:variable name='id' select='@bind'/>
            <xsl:for-each select='local:get-model()'>
              <xsl:value-of select='descendant::xf:bind[@id=$id]/@nodeset'/>
            </xsl:for-each>
          </xsl:when>
          <xsl:when test='@nodeset'>
            <xsl:value-of select='@nodeset'/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select='@ref'/>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:if test='position()=last()'>
          <xsl:text>[</xsl:text>
          <xsl:choose>
            <xsl:when test='$index != ""'>
              <xsl:value-of select='$index'/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>1</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
          <xsl:text>]</xsl:text>
        </xsl:if>
        <xsl:text>/</xsl:text>
      </xsl:for-each>
    </xsl:if>
  </func:result>
</func:function>

<func:function name='local:get-encoding'>
  <func:result>
    <xsl:for-each select='local:get-model()/xf:submission'>
          <xsl:variable name='method' select='@method'/>
      <xsl:choose>
        <xsl:when test='@mediatype'>
          <xsl:value-of select='@mediatype'/>
        </xsl:when>
        <xsl:when test='$method="get"or $method="url-encoded-post"'>
          <xsl:value-of select='$urlencoding'/>
        </xsl:when>
        <xsl:when test='$method="form-data-post"'>
          <xsl:value-of select='"multipart/form-data"'/>
        </xsl:when>
      </xsl:choose>
    </xsl:for-each>
  </func:result>
</func:function>

<func:function name='local:get-form-method'>
  <func:result>
    <xsl:for-each select='local:get-model()/xf:submission'>
      <xsl:choose>
        <xsl:when test='@method="get"'>
          <xsl:value-of select='"GET"'/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select='"POST"'/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </func:result>
</func:function>

<func:function name='local:caption-text'>
  <xsl:for-each select='./xf:caption'>
    <xsl:variable name='data' select='local:get-instance-data(1)'/>
    <func:result>
      <xsl:choose>
        <xsl:when test='$data !=""'>
          <xsl:value-of select='$data'/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select='normalize-space(.)'/>
        </xsl:otherwise>
      </xsl:choose>
    </func:result>
  </xsl:for-each>
</func:function>

<func:function name='local:basename'>
  <xsl:param name='path'/>
  <xsl:for-each select='str:tokenize($path,"/")'>
    <xsl:if test='position()=last()'>
      <func:result>
      <xsl:value-of select='.'/>
    </func:result>
    </xsl:if>
  </xsl:for-each>
</func:function>

<func:function name='local:dirname'>
  <xsl:param name='path'/>
  <xsl:variable name='parent'>
    <xsl:for-each select='str:tokenize($path,"/")'>
      <xsl:if test='position() != last()'>
        <xsl:value-of select='.'/>
        <xsl:value-of select='"/"'/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>
  <func:result>
    <xsl:value-of select='$parent'/>
</func:result>
</func:function>

<!-- named templates -->
<xsl:template name='common-attributes'>
  <xsl:if test='@class'>
    <xsl:attribute name='class'>
      <xsl:value-of select='@class'/>
    </xsl:attribute>
  </xsl:if>
  <xsl:if test='@accessKey'>
    <xsl:attribute name='accesskey'>
      <xsl:value-of select='@accessKey'/>
    </xsl:attribute>
  </xsl:if>
</xsl:template>

<xsl:template name='caption'>
  <span class='caption'>
    <xsl:value-of select='local:caption-text()'/>
  </span>
</xsl:template>

<xsl:template name='hint'>
  <xsl:attribute name='title'>
    <xsl:value-of select='normalize-space(xf:hint)'/>
  </xsl:attribute>
</xsl:template>

<xsl:template name='input'>
  <xsl:param name='type'/>
  <xsl:param name='index'/>
  <xsl:variable name='relevant' select='local:get-constraint("@relevant")'/>
  <xsl:if test='$relevant != "false"'>
    <div>
      <xsl:call-template name='get-class-attribute'/>
      <xsl:call-template name='hint'/>
      <xsl:call-template name='caption'/>
      <span class='input'>
        <input 
          name='{local:get-path($index,false())}' 
          value='{local:get-instance-data($index)}'>
          <xsl:attribute name='type'>
            <xsl:value-of select='$type'/>
          </xsl:attribute>
          <xsl:call-template name='common-attributes'/>
        </input>
      </span>
    </div>
  </xsl:if>
  <xsl:text>
  </xsl:text>
</xsl:template>

<xsl:template name='get-repeat'>
  <!-- must be called in model context -->
  <xsl:param name='path'/>
  <xsl:param name='min'/>
  <xsl:param name='max'/>

  <xsl:variable name='node-count' select='count(dyn:evaluate($path))'/>
  <xsl:variable name='parent' select='local:dirname($path)'/>
  <xsl:variable name='count'>
    <xsl:choose>
      <xsl:when test='$node-count &lt; $min'>
        <xsl:value-of select='$min'/>
      </xsl:when>
      <xsl:when test='$max = "unbounded"'>
        <xsl:value-of select='$node-count'/>
      </xsl:when>
      <xsl:when test='$node-count &gt; $max'>
        <xsl:value-of select='$max'/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select='$node-count'/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:call-template name='_get-repeat'>
    <xsl:with-param name='value' select='""'/>
    <xsl:with-param name='i' select='1'/>
    <xsl:with-param name='count' select='$count'/>
  </xsl:call-template>
</xsl:template>

<func:function name='local:get-constraint'>
  <xsl:param name='attribute'/>
  <xsl:variable name ='id'>
    <!-- emacs is messing up, on indent of empty var here... -->
    <xsl:value-of select='@bind'/>
  </xsl:variable>
  <xsl:variable name='scalars'>
    <xsl:text>@type @maxOccurs @minOccurs</xsl:text>
  </xsl:variable>
  <func:result>
    <xsl:if test='$id != ""'>
        <xsl:variable name='value'>
          <xsl:for-each select='local:get-model()'>
            <xsl:for-each select='descendant::xf:bind[@id=$id]'>
              <xsl:value-of select='dyn:evaluate($attribute)'/>
            </xsl:for-each>
          </xsl:for-each>
        </xsl:variable>
        <xsl:choose>
          <xsl:when test='$value = ""'>
            <xsl:value-of 
              select='local:get-constraint-info($attribute,"default")'/>
          </xsl:when>
          <xsl:when test='contains($scalars,$attribute)'>
            <xsl:value-of select='$value'/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:for-each select='local:get-model()'>
              <xsl:for-each select='xf:instance'>
                <xsl:value-of select='dyn:evaluate($value)'/>
              </xsl:for-each>
            </xsl:for-each>
            <!-- not handled yet -->
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
  </func:result>
</func:function>

<func:function name='local:get-constraint-info'>
  <xsl:param name='name'/>
  <xsl:param name='attribute'/>
  <xsl:variable name='scalars'>
    <xsl:text>@type @maxOccurs @minOccurs</xsl:text>
  </xsl:variable>
  
  <func:result>
    <xsl:choose>
      <xsl:when test='$attribute="scalar"'>
        <xsl:value-of select='contains($scalars,$name)'/>
      </xsl:when>
      <xsl:when test='$attribute="default"'>
        
        <xsl:choose>
          <xsl:when test='$name="@type"'>
            <xsl:text>string</xsl:text>
          </xsl:when>
          <xsl:when test='$name="@readOnly"'>
            <xsl:value-of select='false()'/>
          </xsl:when>
          <xsl:when test='$name="@required"'>
            <xsl:value-of select='false()'/>
          </xsl:when>
          <xsl:when test='$name="@relevant"'>
            <xsl:value-of select='true()'/>
          </xsl:when>
          <xsl:when test='$name="@isValid"'>
            <xsl:value-of select='true()'/>
          </xsl:when>
          <xsl:when test='$name="@maxOccurs"'>
            <xsl:text>unbounded</xsl:text>
          </xsl:when>
          <xsl:when test='$name="@minOccurs"'>
            <xsl:value-of select='0'/>
          </xsl:when>
        </xsl:choose>
      </xsl:when>
    </xsl:choose>
  </func:result>
</func:function> 

<func:function name='local:encoded-node'>
  <xsl:param name='end'/>
  <func:result>
  <xsl:text>&lt;</xsl:text>
  <xsl:if test='$end'>
    <xsl:text>/</xsl:text>
  </xsl:if>
  <xsl:if test='namespace-uri()'>
    <xsl:value-of select='namespace-uri()'/>:
  </xsl:if>
  <xsl:value-of select='local-name()'/>
  <xsl:if test='not($end)'>
    <xsl:value-of select='local:encoded-attributes()'/>
  </xsl:if>
  <xsl:text>&gt;</xsl:text>
</func:result>
</func:function>

<func:function name='local:encoded-attributes'>
  <func:result>
    <xsl:for-each select='@*'>
      <xsl:text> </xsl:text>
      <xsl:value-of select='local-name()'/>
      <xsl:text>=</xsl:text>
      <xsl:text>"</xsl:text>
      <xsl:value-of select='.'/>
      <xsl:text>"</xsl:text>
    </xsl:for-each>
</func:result>
</func:function>

<xsl:template name='_get-repeat'>
  <xsl:param name='value'/>
  <xsl:param name='i'/>
  <xsl:param name='count'/>
  <xsl:choose>
    <xsl:when test='$i > $count'>
    <xsl:value-of select='$value'/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name='_get-repeat'>
        <xsl:with-param name='value' select='concat($value," ",$i)'/>
        <xsl:with-param name='i' select='$i+1'/>
        <xsl:with-param name='count' select='$count'/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name='get-class-attribute'>
  <xsl:param name='class' select='"input"'/>
  <xsl:variable name='required' 
          select='local:get-constraint("@required")'/>
  <xsl:variable name='valid'
    select='local:get-constraint("@isValid")'/>

  <xsl:attribute name='class'>
    <xsl:value-of select='$class'/>
    <xsl:if test='$required = "true"'>
      <xsl:text> required</xsl:text>
    </xsl:if>
    <xsl:if test='$valid = "false"'>
      <xsl:text> invalid</xsl:text>
    </xsl:if>
  </xsl:attribute>
</xsl:template>

</xsl:stylesheet>
